package com.atwy.account.service.Impl;

import com.atwy.account.mapper.AccountMapper;
import com.atwy.account.model.AccountDo;
import com.atwy.account.service.AccountService;
import io.seata.rm.tcc.api.BusinessActionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

@Service
public class AccountServiceImpl implements AccountService {

    private static final Logger log = LoggerFactory.getLogger(AccountServiceImpl.class);
    @Autowired
    AccountMapper accountMapper;

    /**
     * 一阶段，预处理
     *
     * @param userId
     * @param money
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean prepare(String userId, double money) {
        AccountDo account = accountMapper.getAccountByUserId(userId);
        if (account == null) {
            throw new RuntimeException("账户不存在");
        }
        if (account.getMoney() < money) {
            throw new RuntimeException("账户余额不足，预扣款失败");
        }
        account.setFreezeMoney(account.getFreezeMoney() + money);
        account.setMoney(account.getMoney() - money);
        Integer i = accountMapper.updateAccount(account);
        log.info("{}预扣款，{}", userId, money);
        return i == 1;
    }

    /**
     * 二阶段，正式提交
     *
     * @param businessActionContext
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean release(BusinessActionContext businessActionContext) {
        String userId = (String) businessActionContext.getActionContext("userId");
        double money = ((BigDecimal)businessActionContext.getActionContext("money")).doubleValue();
        AccountDo account = accountMapper.getAccountByUserId(userId);
        if (account.getFreezeMoney() < money) {
            throw new RuntimeException("账户余额不足，扣款失败");
        }
        account.setFreezeMoney(account.getFreezeMoney() - money);
        log.info("账户扣款成功,进行提交,userid:{},money:{}", userId, money);
        int i = accountMapper.updateAccount(account);
        return i == 1;
    }

    /**
     * 二阶段，回滚
     *
     * @param businessActionContext
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean rollbackMoney(BusinessActionContext businessActionContext) {
        String userId = (String) businessActionContext.getActionContext("userId");
        double money = ((BigDecimal)businessActionContext.getActionContext("money")).doubleValue();
        log.info("账户失败，回滚,userid:{},money:{}", userId, money);
        AccountDo account = accountMapper.getAccountByUserId(userId);
        if (account.getFreezeMoney() >= money) {
            account.setFreezeMoney(account.getFreezeMoney() - money);
            account.setMoney(account.getMoney() + money);
            int i = accountMapper.updateAccount(account);
            log.info("{}账户释放冻结金额{}元", userId, money);
            return i == 1;
        }
        log.info("{}账户冻结金额已释放", userId);
        return true;
    }
}
